<!DOCTYPE html>
<html lang="en-us">
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
<meta charset="UTF-8">
<title>Multidocument Patterns | Elasticsearch: The Definitive Guide [2.x] | Elastic</title>
<link rel="home" href="index.html" title="Elasticsearch: The Definitive Guide [2.x]">
<link rel="up" href="distributed-docs.html" title="Distributed Document Store">
<link rel="prev" href="_partial_updates_to_a_document.html" title="Partial Updates to a Document">
<link rel="next" href="search.html" title="Searching—​The Basic Tools">
<meta name="DC.type" content="Learn/Docs/Legacy/Elasticsearch/Definitive Guide/2.x">
<meta name="DC.subject" content="Elasticsearch">
<meta name="DC.identifier" content="2.x">
<meta name="robots" content="noindex,nofollow">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.optimizely.com/js/18132920325.js"></script>
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
    <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
    <link rel="manifest" href="/manifest.json">
    <meta name="apple-mobile-web-app-title" content="Elastic">
    <meta name="application-name" content="Elastic">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="/mstile-144x144.png">
    <meta name="theme-color" content="#ffffff">
    <meta name="naver-site-verification" content="936882c1853b701b3cef3721758d80535413dbfd">
    <meta name="yandex-verification" content="d8a47e95d0972434">
    <meta name="localized" content="true">
    <meta name="st:robots" content="follow,index">
    <meta property="og:image" content="https://www.elastic.co/static/images/elastic-logo-200.png">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" href="/favicon.ico" type="image/x-icon">
    <link rel="apple-touch-icon-precomposed" sizes="64x64" href="/favicon_64x64_16bit.png">
    <link rel="apple-touch-icon-precomposed" sizes="32x32" href="/favicon_32x32.png">
    <link rel="apple-touch-icon-precomposed" sizes="16x16" href="/favicon_16x16.png">
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="/guide/static/styles.css">
  </head>

  <!--© 2015-2021 Elasticsearch B.V. Copying, publishing and/or distributing without written permission is strictly prohibited.-->

  <body>
    <!-- Google Tag Manager -->
    <script>dataLayer = [];</script><noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-58RLH5" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-58RLH5');</script>
    <!-- End Google Tag Manager -->

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-12395217-16"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'UA-12395217-16');
    </script>

    <!--BEGIN QUALTRICS WEBSITE FEEDBACK SNIPPET-->
    <script type="text/javascript">
      (function(){var g=function(e,h,f,g){
      this.get=function(a){for(var a=a+"=",c=document.cookie.split(";"),b=0,e=c.length;b<e;b++){for(var d=c[b];" "==d.charAt(0);)d=d.substring(1,d.length);if(0==d.indexOf(a))return d.substring(a.length,d.length)}return null};
      this.set=function(a,c){var b="",b=new Date;b.setTime(b.getTime()+6048E5);b="; expires="+b.toGMTString();document.cookie=a+"="+c+b+"; path=/; "};
      this.check=function(){var a=this.get(f);if(a)a=a.split(":");else if(100!=e)"v"==h&&(e=Math.random()>=e/100?0:100),a=[h,e,0],this.set(f,a.join(":"));else return!0;var c=a[1];if(100==c)return!0;switch(a[0]){case "v":return!1;case "r":return c=a[2]%Math.floor(100/c),a[2]++,this.set(f,a.join(":")),!c}return!0};
      this.go=function(){if(this.check()){var a=document.createElement("script");a.type="text/javascript";a.src=g;document.body&&document.body.appendChild(a)}};
      this.start=function(){var a=this;window.addEventListener?window.addEventListener("load",function(){a.go()},!1):window.attachEvent&&window.attachEvent("onload",function(){a.go()})}};
      try{(new g(100,"r","QSI_S_ZN_emkP0oSe9Qrn7kF","https://znemkp0ose9qrn7kf-elastic.siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_ZID=ZN_emkP0oSe9Qrn7kF")).start()}catch(i){}})();
    </script><div id="ZN_emkP0oSe9Qrn7kF"><!--DO NOT REMOVE-CONTENTS PLACED HERE--></div>
    <!--END WEBSITE FEEDBACK SNIPPET-->

    <div id="elastic-nav" style="display:none;"></div>
    <script src="https://www.elastic.co/elastic-nav.js"></script>

    <!-- Subnav -->
    <div>
      <div>
        <div class="tertiary-nav d-none d-md-block">
          <div class="container">
            <div class="p-t-b-15 d-flex justify-content-between nav-container">
              <div class="breadcrum-wrapper"><span><a href="/guide/" style="font-size: 14px; font-weight: 600; color: #000;">Docs</a></span></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="main-container">
      <section id="content">
        <div class="content-wrapper">

          <section id="guide" lang="en">
            <div class="container">
              <div class="row">
                <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                  <!-- start body -->
                  <div class="page_header">
<p>
  <strong>WARNING</strong>: The 2.x versions of Elasticsearch have passed their
  <a href="https://www.elastic.co/support/eol">EOL dates</a>. If you are running
  a 2.x version, we strongly advise you to upgrade.
</p>
<p>
  This documentation is no longer maintained and may be removed. For the latest
  information, see the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">current
  Elasticsearch documentation</a>.
</p>
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: The Definitive Guide [2.x]</a></span>
»
<span class="breadcrumb-link"><a href="getting-started.html">Getting Started</a></span>
»
<span class="breadcrumb-link"><a href="distributed-docs.html">Distributed Document Store</a></span>
»
<span class="breadcrumb-node">Multidocument Patterns</span>
</div>
<div class="navheader">
<span class="prev">
<a href="_partial_updates_to_a_document.html">« Partial Updates to a Document</a>
</span>
<span class="next">
<a href="search.html">Searching—​The Basic Tools »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="distrib-multi-doc"></a>Multidocument Patterns<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/040_Distributed_CRUD/30_Bulk_requests.asciidoc">edit</a>
</h2>
</div></div></div>
<p>The patterns for the <code class="literal">mget</code> and <code class="literal">bulk</code> APIs are similar to those for
individual documents. The difference is that the coordinating node knows in
which shard each document lives. It breaks up the multidocument request into
a multidocument request <em>per shard</em>, and forwards these in parallel to each
participating node.</p>
<p>Once it receives answers from each node, it collates their responses
into a single response, which it returns to the client, as shown in <a class="xref" href="distrib-multi-doc.html#img-distrib-mget" title="Retrieving multiple documents with mget">Figure 12, “Retrieving multiple documents with <code class="literal">mget</code>”</a>.</p>
<div id="img-distrib-mget" class="imageblock">
<div class="content">
<img src="images/elas_0405.png" alt="Retrieving multiple documents with mget">
</div>
<div class="title">Figure 12. Retrieving multiple documents with <code class="literal">mget</code>
</div>
</div>
<p>Here is the sequence of steps necessary to retrieve multiple documents
with a single <code class="literal">mget</code> request:</p>
<div class="olist orderedlist">
<ol class="orderedlist">
<li class="listitem">
The client sends an <code class="literal">mget</code> request to <code class="literal">Node 1</code>.
</li>
<li class="listitem">
<code class="literal">Node 1</code> builds a multi-get request per shard, and forwards these
requests in parallel to the nodes hosting each required primary or replica
shard. Once all replies have been received, <code class="literal">Node 1</code> builds the response
and returns it to the client.
</li>
</ol>
</div>
<p>A <code class="literal">routing</code> parameter can be set for each document in the <code class="literal">docs</code> array.</p>
<p>The bulk API, as depicted in <a class="xref" href="distrib-multi-doc.html#img-distrib-bulk" title="Multiple document changes with bulk">Figure 13, “Multiple document changes with <code class="literal">bulk</code>”</a>, allows the execution of multiple create, index, delete, and update requests within a single bulk request.</p>
<div id="img-distrib-bulk" class="imageblock">
<div class="content">
<img src="images/elas_0406.png" alt="Multiple document changes with bulk">
</div>
<div class="title">Figure 13. Multiple document changes with <code class="literal">bulk</code>
</div>
</div>
<p>The sequence of steps followed by the
<code class="literal">bulk</code> API are as follows:</p>
<div class="olist orderedlist">
<ol class="orderedlist">
<li class="listitem">
The client sends a <code class="literal">bulk</code> request to <code class="literal">Node 1</code>.
</li>
<li class="listitem">
<code class="literal">Node 1</code> builds a bulk request per shard, and forwards these requests in
parallel to the nodes hosting each involved primary shard.
</li>
<li class="listitem">
The primary shard executes each action serially, one after another. As each
action succeeds, the primary forwards the new document (or deletion) to its
replica shards in parallel, and then moves on to the next action. Once all
replica shards report success for all actions, the node reports success to
the coordinating node, which collates the responses and returns them to the
client.
</li>
</ol>
</div>
<p>The <code class="literal">bulk</code> API also accepts  the <code class="literal">consistency</code> parameter
at the top level for the whole <code class="literal">bulk</code> request, and the <code class="literal">routing</code> parameter
in the metadata for each request.</p>
<div class="section pagebreak-before">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="bulk-format"></a>Why the Funny Format?<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/040_Distributed_CRUD/35_Bulk_format.asciidoc">edit</a>
</h3>
</div></div></div>
<p>When we learned about bulk requests earlier in <a class="xref" href="bulk.html" title="Cheaper in Bulk">Cheaper in Bulk</a>, you may have asked
yourself, “Why does the <code class="literal">bulk</code> API require the funny format with the newline
characters, instead of just sending the requests wrapped in a JSON array, like
the <code class="literal">mget</code> API?”</p>
<p>To answer this, we need to explain a little background: Each document referenced in a bulk request may belong to a different primary
shard, each of which may be allocated to any of the nodes in the cluster. This
means that every <em>action</em> inside a <code class="literal">bulk</code> request needs to be forwarded to the
correct shard on the correct node.</p>
<p>If the individual requests were wrapped up in a JSON array, that would mean
that we would need to do the following:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
Parse the JSON into an array (including the document data, which
can be very large)
</li>
<li class="listitem">
Look at each request to determine which shard it should go to
</li>
<li class="listitem">
Create an array of requests for each shard
</li>
<li class="listitem">
Serialize these arrays into the internal transport format
</li>
<li class="listitem">
Send the requests to each shard
</li>
</ul>
</div>
<p>It would work, but would need a lot of RAM to hold copies of essentially
the same data, and would create many more data structures that the Java Virtual Machine (JVM) would have to spend time garbage collecting.</p>
<p>Instead, Elasticsearch reaches up into the networking buffer, where the raw
request has been received, and reads the data directly. It uses the newline
characters to identify and parse just the small <code class="literal">action/metadata</code> lines in
order to decide which shard should handle each request.</p>
<p>These raw requests are forwarded directly to the correct shard. There
is no redundant copying of data, no wasted data structures. The entire
request process is handled in the smallest amount of memory possible.</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="_partial_updates_to_a_document.html">« Partial Updates to a Document</a>
</span>
<span class="next">
<a href="search.html">Searching—​The Basic Tools »</a>
</span>
</div>
</div>

                  <!-- end body -->
                </div>
                <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                  <div id="rtpcontainer" style="display: block;">
                    <div class="mktg-promo">
                      <h3>Most Popular</h3>
                      <ul class="icons">
                        <li class="icon-elasticsearch-white"><a href="https://www.elastic.co/webinars/getting-started-elasticsearch?baymax=default&amp;elektra=docs&amp;storm=top-video">Get Started with Elasticsearch: Video</a></li>
                        <li class="icon-kibana-white"><a href="https://www.elastic.co/webinars/getting-started-kibana?baymax=default&amp;elektra=docs&amp;storm=top-video">Intro to Kibana: Video</a></li>
                        <li class="icon-logstash-white"><a href="https://www.elastic.co/webinars/introduction-elk-stack?baymax=default&amp;elektra=docs&amp;storm=top-video">ELK for Logs &amp; Metrics: Video</a></li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>

        </div>


<div id="elastic-footer"></div>
<script src="https://www.elastic.co/elastic-footer.js"></script>
<!-- Footer Section end-->

      </section>
    </div>

<script src="/guide/static/jquery.js"></script>
<script type="text/javascript" src="/guide/static/docs.js"></script>
<script type="text/javascript">
  window.initial_state = {}</script>
  </body>
</html>
